package kroketwebspring.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;

import kroketwebspring.domain.Product;

public class ProductDAOImpl extends JdbcDaoSupport implements ProductDAO {
	
	@SuppressWarnings("unchecked")
	@Override
	public HashMap<Integer, Product> getAllProductsFromSession(HttpSession session) {
		HashMap<Integer, Product> products = (HashMap<Integer, Product>) session.getAttribute("products");
		if (products == null) {
			products = new HashMap<Integer, Product>();
		}
		return products;
	}

	@Override
	public int getProductCount() {
		String query = "SELECT COUNT(p.product_id) as product_count"
			+ " FROM product p"
			+ " INNER JOIN price q"
			+ " ON p.product_id = q.product_id"
			+ " WHERE q.price_sDate < NOW()"
			+ " AND (q.price_eDate > NOW() OR q.price_eDate IS NULL);";
		
		int productCount = this.getJdbcTemplate().queryForInt(query);
		
		return productCount;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Product getProduct(int id, HttpSession session) {
		HashMap<Integer, Product> products = (HashMap<Integer, Product>) session.getAttribute("products");
		if (products != null) {
			return products.get(id);
		} else {
			return null;
		}
	}

	@Override
	public List<Product> getProducts(int start, int amount) {
		return getSortedProducts('N', start, amount);
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Product> getSortedProducts(char order, int start, int amount) {
		// switch over the possible means to order
		String orderString;
		switch (order) {
		case 'N':
			orderString = "p.product_name";
			break;
		case 'P':
			orderString = "q.price_value";
			break;
		case 'S':
			orderString = "p.product_stock";
			break;
		default:
			orderString = "p.product_name";
			break;
		}
		
		// Prepare query
		String query = "SELECT p.product_id AS product_id, p.product_name AS product_name, p.product_stock AS product_stock, q.price_value AS price_value"
			+ " FROM product p"
			+ " INNER JOIN price q"
			+ " ON p.product_id = q.product_id"
			+ " WHERE q.price_sDate < NOW()"
			+ " AND (q.price_eDate > NOW() OR q.price_eDate IS NULL)"
			+ " ORDER BY " + orderString 
			+ " LIMIT " + start + ", " + amount + ";";
		
		List<Product> productList = this.getJdbcTemplate().query(query, new ParameterizedRowMapper<Product>() {
			public Product mapRow(final ResultSet rs, final int rowNum) throws SQLException {
				Product output = new Product();
				output.setId(rs.getInt("product_id"));
				output.setName(rs.getString("product_name"));
				output.setStock(rs.getInt("product_stock"));
				output.setPrice(rs.getFloat("price_value"));
				return output;
			}
		});
		return productList;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void addProductToSession(int id, final int amount, HttpSession session) {
		HashMap<Integer, Product> products = (HashMap<Integer, Product>) getAllProductsFromSession(session);
		// get product info from database
		String query = "SELECT p.product_id AS product_id, p.product_name AS product_name, p.product_stock AS product_stock, q.price_value AS price_value"
			+ " FROM product p"
			+ " INNER JOIN price q"
			+ " ON p.product_id = q.product_id"
			+ " WHERE p.product_id = " + id + "" 
			+ " LIMIT 1;";
		List<Product> productList = this.getJdbcTemplate().query(query, new ParameterizedRowMapper<Product>() {
			public Product mapRow(final ResultSet rs, final int rowNum) throws SQLException {
				Product output = new Product();
				output.setId(rs.getInt("product_id"));
				output.setName(rs.getString("product_name"));
				output.setStock(rs.getInt("product_stock"));
				output.setAmount(amount);
				output.setPrice(rs.getFloat("price_value"));
				return output;
			}
		});
		
		// add product to hashmap
		Product p = productList.get(0);
		if (p != null) {
			products.put(id, p);
		}
		
		// put products back into the session
		session.setAttribute("products", products);
	}

	@Override
	public void removeProductFromSession(int id, HttpSession session) {
		HashMap<Integer, Product> products = (HashMap<Integer, Product>) getAllProductsFromSession(session);
		
		// remove the product
		products.remove(id);
		
		// put products back into the session
		session.setAttribute("products", products);
	}
	
	@Override
	public ArrayList<Product> getProductsArrayList(HttpSession session) {
		ArrayList<Product> temp = new ArrayList<Product>();
		HashMap<Integer, Product> products = (HashMap<Integer, Product>) getAllProductsFromSession(session);
		
		for (Product p : products.values()) {
			temp.add(p);
		}
		
		return temp;
	}
}
